package edu.gzhu.guli.core.repository.support;

import org.springframework.data.jpa.domain.Specification;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Date;

public final class SpecificationFactory {
  /**
   * 模糊查询，匹配对应字段
   */
  public static <T> Specification<T> containsLike(String attribute, String value) {
    return (root, query, cb) -> cb.like(root.get(attribute), "%" + value + "%");
  }

  /**
   * 某字段的值等于 value 的查询条件
   */
  public static <T> Specification<T> equal(String attribute, Object value) {
    return (root, query, cb) -> cb.equal(root.get(attribute), value);
  }

  /**
   * 获取对应属性的值所在区间
   */
  public static <T> Specification<T> isBetween(String attribute, int min, int max) {
    return (root, query, cb) -> cb.between(root.get(attribute), min, max);
  }

  public static <T> Specification<T> isBetween(String attribute, double min, double max) {
    return (root, query, cb) -> cb.between(root.get(attribute), min, max);
  }

  public static <T> Specification<T> isBetween(String attribute, Date min, Date max) {
    return (root, query, cb) -> cb.between(root.get(attribute), min, max);
  }

  public static <T> Specification<T> isBetween(String attribute, LocalDateTime min, LocalDateTime max) {
    return (root, query, cb) -> cb.between(root.get(attribute), min, max);
  }

  public static <T> Specification<T> isBetween(String attribute, LocalDate min, LocalDate max) {
    return (root, query, cb) -> cb.between(root.get(attribute), min, max);
  }

  /**
   * 通过属性名和集合实现 in 查询
   */
  public static <T> Specification<T> in(String attribute, Collection<?> c) {
    return (root, query, cb) -> root.get(attribute).in(c);
  }

  /**
   * 通过属性名构建大于等于 Value 的查询条件
   */
  public static <T> Specification<T> greaterThan(String attribute, BigDecimal value) {
    return (root, query, cb) -> cb.greaterThan(root.get(attribute), value);
  }

  public static <T> Specification<T> greaterThan(String attribute, Long value) {
    return (root, query, cb) -> cb.greaterThan(root.get(attribute), value);
  }
}